# Chapter 11

# Real-Life Examples II

CONTENTS

- Example 1: Nonscrolling Status Line Messages
- Example 2: An Improved Navigation Bar
- Example 3: Storing User Preference

This chapter includes several example JavaScript applications that apply the techniques you learned in Part III, "Creating Smart Web Pages." These include the following:

- Example 1: Nonscrolling Status Line Messages: A different idea for displaying messages in the status line
- Example 2: An Improved Navigation Bar: Using dynamically changed selection lists to allow the user to select a specific page
- Example 3: Storing User Preferences: A page that remembers a user's preference and shows either the frames or no-frames version

## Example 1: Nonscrolling Status Line Messages

Chapter 8 "Improving a Web Page with JavaScript," introduced a program to scroll messages in the browser's status line. Such scrolling messages have become a bit of a cliché on the Web, and they do have their disadvantages-for one, few users want to watch for several minutes while a long message displays.

The following techniques are used in this example:

- Using timeouts to display messages (Chapter 8)
- Displaying instructions for links (Chapter 8)
- Storing data in string arrays (Chapter 10)

One alternative is to display messages that don't scroll in the status line. This enables you to have several different tips, advertisements, or other messages displayed, and enables the user to read them quickly.

Listing 11.1 shows the nonscrolling message program integrated into the FSC Software home page. You'll look at the program in detail later.

> Listing 11.1. (NOSCROLL.htm) Random, nonscrolling messages in the status line.

>     <HTML>
>     <HEAD>
>     <TITLE>Fictional Software Company</TITLE>
>     <SCRIPT>
>     // messages to display in scrollbar
>     msg = new Array(4);
>     msg[0]="This is the first message."
>     msg[1]="This is the second message."
>     msg[2]="This is the third message."
>     msg[3]="This is the fourth message."

>     //flag to control message
>     var showmsg = true;
>     function NextMessage() {
>        if (!showmsg) {
>           window.setTimeout("NextMessage()",5000);
>           showmsg = true;
>           return;
>        }
>        index = Math.floor(msg.length * Math.random());
>        window.status = msg[index];
>     // set timeout for next update
>        window.setTimeout("NextMessage()",5000);
>     }
>     // Display the first status line message
>     NextMessage();
>     // Display a link help message
>     function LinkMessage(text) {
>        showmsg = false;
>        window.status = text;
>     }
>     </SCRIPT>
>     </HEAD>
>     <BODY>
>     <IMG SRC="fsclogo.gif" alt="Fictional Software Company">
>     <HR>
>     Welcome to our web page! Fictional Software Company
>     specializes in creating innovative, user-friendly software
>     applications with descriptions filled with industry
>     buzzwords.
>     <P>
>     We have a wide range of products (3 of them) to meet
>     the needs of you and your company. Follow the links
>     below for more information.
>     <P>
>     <UL>
>     <LI><A HREF="spread.htm"
>     onMouseOver="LinkMessage('Information about the spreadsheet');return true;">
>     Fictional Spreadsheet 7.0</A>
>     <LI><A HREF="word.htm"
>     onMouseOver="LinkMessage('Information about the word processor');return true;">
>     Fictional Word Processor 6.0</A>
>     <LI><A HREF="data.htm"
>     onMouseOver="LinkMessage('Information about the database');return true;">
>     Fictional Database 7.0</A>
>     </UL>
>     <P>
>     Unlike other software companies, our products have
>     absolutely no bugs, and always work perfectly on all
>     computers. Nevertheless, you may run into problems in
>     rare cases, usually your own fault. If this happens,
>     visit our <A HREF="support.htm"
>     onMouseOver="LinkMessage('Technical Support for our products');return true;">
>     Technical Support</A>
>     department for helpful information and tips. You can
>     also view more information <A HREF="company.htm"
>     onMouseOver="LinkMessage('Information about FSC Software Co.');return true;">
>     about our company</A> or order products with our friendly
>     <a href="order.htm"
>     onMouseOver="LinkMessage('Allows you to order products');return true;">
>     Order Form</A>.
>     <HR>
>     <I>(c)1998 FSC - designed by the FSC staff</I>
>     </BODY>
>     </HTML>

Here's a summary of how key elements of this program work:

- An array, `msg[]`, is created to hold the various messages that will be displayed.
- Each element of the `msg` array is assigned explicitly. This example has four messages, but there could easily be more.
- Every five seconds, a new random index into the `msg` array is created using the `Math.random()` method. The resulting string is stored in `window.status` to display it in the status line.
- This program also implements the "friendly links" technique used in Chapter 8. The `showmessage` flag is used to turn off the random messages when a link description is being displayed.

Note
This program uses the `Math.random()` method, which was fully implemented in Netscape 3.0b3, although it worked in earlier UNIX versions. Be sure you're using the latest version to try this example.

This program is shown in action in Figure 11.1. I hope this not only gives you an alternative way of displaying messages, but the inspiration to come up with new and creative ways of your own.

Figure 11.1 : Netscape's display of the nonscrolling message example.

## Example 2: An Improved Navigation Bar

You created a navigation bar for the FSC home page in Chapter 8. In that example, each product had the same list of categories available. What if there is a different list of pages for each product? In this example, you'll use dynamic selection lists to allow for different pages for each product.

This example uses the following techniques:

- Using selection lists for navigation (Chapter 8)
- Complex site organization and planning (Chapter 10)

Listing 11.2 shows the improved navigation bar in JavaScript and HTML.

> Listing 11.2. (NAVBAR2.htm) The HTML and JavaScript source for the improved navigation bar.

>     <HTML>
>     <HEAD>
>     <TITLE>Fictional Software Company</TITLE>
>     <SCRIPT>
>     function Navigate() {
>        prod = document.navform.program.selectedIndex;
>        cat = document.navform.category.selectedIndex;
>        prodval = document.navform.program.options[prod].value;
>        catval = document.navform.category.options[cat].value;
>        if (prodval == "x" || catval == "x") return;
>        window.location = prodval + "_" + catval + ".htm";
>     }
>     function update() {
>     // update available categories depending on product
>        prod = document.navform.program.selectedIndex;
>        prodval = document.navform.program.options[prod].value;
>        if (prodval == "x")
>           {document.navform.category.options[0].text = "Select a Category:";
>            document.navform.category.options[0].value = "x";
>            document.navform.category.options[1].text = "(please select ";
>            document.navform.category.options[1].value = "x";
>            document.navform.category.options[2].text = " a product";
>            document.navform.category.options[2].value = "x";
>            document.navform.category.options[3].text = " first)";
>            document.navform.category.options[3].value = "x";
>           }
>        if (prodval == "w")
>           {document.navform.category.options[0].text = "Word Processor:";
>            document.navform.category.options[0].value = "x";
>            document.navform.category.options[1].text = "Technical Support";
>            document.navform.category.options[1].value = "tech";
>            document.navform.category.options[2].text = "Pricing Information";
>            document.navform.category.options[2].value = "price";
>            document.navform.category.options[3].text = "Tips and Tricks";
>            document.navform.category.options[3].value = "tips";
>           }
>        if (prodval == "s")
>           {document.navform.category.options[0].text = "Spreadsheet:";
>            document.navform.category.options[0].value = "x";
>            document.navform.category.options[1].text = "Technical Support";
>            document.navform.category.options[1].value = "tech";
>            document.navform.category.options[2].text = "Distributors";
>            document.navform.category.options[2].value = "dist";
>            document.navform.category.options[3].text = "Sample Formulas";
>            document.navform.category.options[3].value = "form";
>           }
>        if (prodval == "d")
>           {document.navform.category.options[0].text = "Database:";
>            document.navform.category.options[0].value = "x";
>            document.navform.category.options[1].text = "Technical Support";
>            document.navform.category.options[1].value = "tech";
>            document.navform.category.options[2].text = "Pricing Information";
>            document.navform.category.options[2].value = "price";
>            document.navform.category.options[3].text = "Sample Programs";
>            document.navform.category.options[3].value = "prog";
>           }
>     }
>     </SCRIPT>
>     </HEAD>
>     <BODY>
>     <IMG SRC="fsclogo.gif" alt="Fictional Software Company">
>     <HR>
>     Welcome to our web page! Fictional Software Company
>     specializes in creating innovative, user-friendly software
>     applications with descriptions filled with industry
>     buzzwords.
>     <P>
>     We have a wide range of products (3 of them) to meet
>     the needs of you and your company. Follow the links
>     below for more information.
>     <P>
>     <FORM name="navform">
>     <SELECT name="program"
>      onChange="update();">
>     <OPTION VALUE="x" SELECTED>Select a Product
>     <OPTION VALUE="w">Fictional Word Processor
>     <OPTION VALUE="s">Fictional Spreadsheet
>     <OPTION VALUE="d">Fictional Database
>     </SELECT>
>     <SELECT name="category">
>     <OPTION VALUE="x" SELECTED>Select a Category:
>     <OPTION VALUE="x"> (Please select
>     <OPTION VALUE="x"> a product
>     <OPTION VALUE="x"> first)
>     </SELECT>
>     <INPUT TYPE="button" NAME="go" VALUE="Go to Page"
>     onClick="Navigate();">
>     </FORM>
>     <P>
>     Unlike other software companies, our products have
>     absolutely no bugs, and always work perfectly on all
>     computers. Nevertheless, you may run into problems in
>     rare cases, usually your own fault. If this happens,
>     visit our <A HREF="support.htm">Technical Support</A>
>     department for helpful information and tips. You can
>     also view more information <A HREF="company.htm">about
>     our company</A> or order products with our friendly
>     <a href="order.htm">Order Form</A>.
>     <HR>
>     <I>(c)1998 FSC - designed by the FSC staff</I>
>     </BODY>
>     </HTML>

The program works as follows:

- The initial state of the selection lists provides instructions. The Go button doesn't work until the user selects an option.
- An `onChange` event handler is used to change the list of categories automatically when the user selects a product.
- The `update()` function handles the modification of the selection list. Both the `text` property, which defines the value displayed on the screen, and the `value` property, which defines the returned value, are changed.

As you can see, this is a much more interactive use of JavaScript-and a more practical one because you will rarely have exactly the same list of pages for each product. This could easily be adapted for a wide variety of uses.

Figure 11.2 shows this example in action. Here are a few observations about this program:

Figure 11.2 : The improved navigation bar example, as displayed by Netscape.

- The technique of changing selection lists was added in Netscape 3.0b4. This may not be available to all your users, and it will cause an error on earlier versions.
- Notice that although you change the list of categories, there are always four of them. I did this to keep things simple; you could also add and delete options. To add an option, use the `Option()` constructor to create a new object, assign its `text` property, and assign it to the last element of the `options` array. To delete items, assign their place in the array to `null`, starting at the end of the `options` array.
- Notice that you change the first option of the category when a product is selected, to prompt the user and indicate the selection. This makes it a bit more friendly than the original navigation bar.
- There may be problems if you try to assign a value to a selection list's text property that is longer than the value it replaces, because Netscape allocates space for the list when the page is first displayed. A solution is to be sure that one of the original options is longer than any others you will use, or explicitly refresh the page with the `location.reload()` method.

## Example 3: Storing User Preference

This example is a useful application for cookies (Chapter 9). You will use a cookie to indicate the user's preference and either display a frames or no-frames version of the page.

This example illustrates the following techniques:

- Storing and retrieving cookies (Chapter 9)
- Controlling frames dynamically (Chapter 10)

This example is a bit more complicated. Let's begin with the page shown in Listing 11.3. This page is an introductory page that will send users to the appropriate page-probably before they even notice.

> Listing 11.3. (SELFRAMES.htm) Introductory page for the user preferences example.

>     <HTML>
>     <HEAD>
>     <TITLE>Frames or No Frames?</TITLE>
>     <SCRIPT LANGUAGE="JavaScript">
>     function forward() {
>     // read cookie and send user to appropriate page
>     if (0 <= parseInt(document.cookie.indexOf('frames=yes', 0)))
>        window.location.href="frames.htm";
>     else
>        window.location.href="noframes.htm";
>     }
>     </SCRIPT>
>     </HEAD>
>     <BODY onLoad="window.setTimeout('forward();',1000);">
>     If you can read this, you're using a non-JavaScript browser. Please follow
>     one of the links below to access our page:
>     <UL>
>     <LI><a href="frames.htm">Frames version</a>
>     <LI><a href="noframes.htm">Non-Frames version</a>
>     </UL>
>     </BODY>
>     </HTML>

This program attempts to read the cookie for the current document with the `document.cookie` property. If it contains the keyword `"frames=yes"`, the user will be sent to the frames version; otherwise, the user is sent to the no-frames page. (Thus, no frames is the default.)

Next, you will need the actual framed and non-framed pages. Listing 11.4 shows the page for the frames version, which includes an option to switch to the no-frames version.

> Listing 11.4. (FRAMES.htm) The frames version of the page.

>     <HTML>
>     <HEAD>
>     <TITLE>Our Home Page (Frames)</TITLE>
>     <SCRIPT LANGUAGE="JavaScript">
>     function goNoFrames() {
>     // switch preference to non-frames version, and send the user there.
>     document.cookie = "frames=no; expires=Monday, 31-Dec-99 23:59:59 GMT";
>     window.location = "noframes.htm";
>     }
>     </SCRIPT>
>     </HEAD>
>     <BODY>
>     <H1>This is the Frames Page</H1>
>     <FORM name="form1">
>     <INPUT TYPE="button" VALUE="Non-Frames Version" onClick="goNoFrames();">
>     </FORM>
>     Welcome to the frames page! If you would like to see the non-frames
>     version, press the button above.
>     <HR>
>     The actual content of the page would be here...
>     <HR>
>     </BODY>
>     </HTML>

To simplify the example, I didn't actually use frames in this page; that would require using a `FRAMESET` document as the initial frames page and creating a second page with the content.

The `GoNoFrames()` function, accessed with the button on the page, enables the user to switch to the no-frames page. This sets a cookie indicating the preference, then updates `window.location` to send the user there.

Similarly, Listing 11.5 shows the no-frames version. This page includes an option to switch to the frames version, including setting the cookie appropriately. Figure 11.3 shows the output of this page.

Figure 11.3 : The No Frames Page for the preferences example.

> Listing 11.5. (NOFRAMES.htm) The no-frames page for the preferences example.

>     <HTML>
>     <HEAD>
>     <TITLE>Our Home Page (No frames)</TITLE>
>     <SCRIPT LANGUAGE="JavaScript">
>     function goFrames() {
>     // switch preference to frames version, and send the user there.
>     document.cookie = "frames=yes; expires=Monday, 31-Dec-99 23:59:59 GMT";
>     window.location = "frames.htm";
>     }
>     </SCRIPT>
>     </HEAD>
>     <BODY>
>     <H1>This is the No Frames Page</H1>
>     <FORM name="form1">
>     <INPUT TYPE="button" VALUE="Frames Version" onClick="goFrames();">
>     </FORM>
>     Welcome to the non-frames page! If you would like to see the frames
>     version, press the button above.
>     <HR>
>     The actual content of the page would be here...
>     <HR>
>     </BODY>
>     </HTML>

Now comes the cool part-once users select one page or the other using the button, they go to that page from then on whenever they load SELFRAMES.htm. Users can change preferences at any time.

Here are a few observations about this example:

- A timeout is used to send the user to the new page by default in SELFRAMES.htm if no cookie has been set. This timeout is required so that the document is finished loading before the browser is redirected to the next page. The timeout could probably be smaller than the one I used.
- You could do this without using an initial page (SELFRAMES.htm) by displaying HTML tags from the script at the beginning of the page. These would include the `<BODY>` or `<FRAMESET>` tags. Needless to say, this would be a bit more complicated.
- The cookie set applies to the server that sent the document. If you are using many pages on the server, you should use a more specific name for the cookie to avoid conflicts. Alternatively, the same preference could be used for all pages.